﻿#include "ProcessManager.h"
#include <TlHelp32.h>
namespace ProcessManager
{
	std::wstring StringToWstring(const char* src)
	{
		wchar_t buff[4096];
		memset(buff, 0, sizeof(wchar_t));
		std::wstring s;
		size_t nCvtCnt;
		int erno = mbstowcs_s(&nCvtCnt, buff, 4096, src, 4096);
		s = buff;
		return std::move(buff);
	}
	using namespace std;
	BOOL IsProcessExits(const char* str)
	{/*
		DWORD dwProcess[1024];
		DWORD dwNeeded = 0;
		BOOL bEnumRes =  EnumProcesses(dwProcess, dwNeeded, &dwNeeded);
		if (bEnumRes == FALSE) return bEnumRes;*/
		PROCESSENTRY32 pe32;
		// 在使用这个结构之前，先设置它的大小
		pe32.dwSize = sizeof(pe32);

		// 给系统内的所有进程拍一个快照
		HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hProcessSnap == INVALID_HANDLE_VALUE)
		{
			printf(" CreateToolhelp32Snapshot调用失败！ \n");
			return FALSE;
		}

		// 遍历进程快照，轮流显示每个进程的信息
		BOOL bMore = ::Process32First(hProcessSnap, &pe32);
		std::wstring wsr;
		std::wstring wsFindProcessName = StringToWstring(str);
		BOOL bFind = FALSE;
		while (bMore)
		{
			wsr = pe32.szExeFile;
			/*printf(" 进程名称：%s \n", pe32.szExeFile);
			printf(" 进程ID号：%u \n\n", pe32.th32ProcessID);*/
			size_t pos = wsr.find(wsFindProcessName);
			wcout << wsr.data() << endl;
			if (pos != std::string::npos)
			{
				bFind = TRUE;
				break;
			}
			bMore = ::Process32Next(hProcessSnap, &pe32);
		}

		// 不要忘记清除掉snapshot对象
		::CloseHandle(hProcessSnap);
		return bFind;
	}

	BOOL GetProcessNameById(DWORD prcessId, char* name)
	{
		PROCESSENTRY32 pe32;
		// 在使用这个结构之前，先设置它的大小
		pe32.dwSize = sizeof(pe32);

		// 给系统内的所有进程拍一个快照
		HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hProcessSnap == INVALID_HANDLE_VALUE)
		{
			printf(" CreateToolhelp32Snapshot调用失败！ \n");
			return FALSE;
		}

		BOOL bMore = ::Process32First(hProcessSnap, &pe32);
		std::wstring wsr;

		while (bMore)
		{
			/*printf(" 进程名称：%s \n", pe32.szExeFile);
			printf(" 进程ID号：%u \n\n", pe32.th32ProcessID);*/
			size_t pos = wsr.find(L"Lark.exe");
			if (pos > 0)
			{
				break;
			}
			std::cout << pos << std::endl;

			bMore = ::Process32Next(hProcessSnap, &pe32);
		}
		// 不要忘记清除掉snapshot对象
		::CloseHandle(hProcessSnap);
	}

	//std::string WstringToString(wchar_t* src)
	//{
	//	char buff[4096];
	//	memset(buff, 0, sizeof(char));
	//	std::string s;
	//	size_t nCvtCnt;
	//	int erno = wcstombs_s(&nCvtCnt, buff, 4096, src, 4096);
	//	s = buff;
	//	return std::move(s);
	//}
	//将wstring转换成string  
	std::string wstring2string(std::wstring wstr)
	{
		std::string result;
		//获取缓冲区大小，并申请空间，缓冲区大小事按字节计算的  
		int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
		char* buffer = new char[len + 1];
		//宽字节编码转换成多字节编码  
		WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
		buffer[len] = '\0';
		//删除缓冲区并返回值  
		result.append(buffer);
		delete[] buffer;
		return result;
	}

	//wstring string2wstring(string str)
	//{
	//	wstring result;
	//	//获取缓冲区大小，并申请空间，缓冲区大小按字符计算  
	//	int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
	//	TCHAR* buffer = new TCHAR[len + 1];
	//	//多字节编码转换成宽字节编码  
	//	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
	//	buffer[len] = '\0';             //添加字符串结尾  
	//	//删除缓冲区并返回值  
	//	result.append(buffer);
	//	delete[] buffer;
	//	return result;
	//}
	BOOL StartProcess(string processName, string arg)
	{
		STARTUPINFOA si;
		ZeroMemory(&si, sizeof(si));
		PROCESS_INFORMATION pi;
		ZeroMemory(&pi, sizeof(pi));

		char ch[1024];
		strcpy_s(ch, arg.data());
		if (CreateProcessA(
			processName.data(),   //  指向一个NULL结尾的、用来指定可执行模块的宽字节字符串  
			ch, // 命令行字符串  
			NULL, //    指向一个SECURITY_ATTRIBUTES结构体，这个结构体决定是否返回的句柄可以被子进程继承。  
			NULL, //    如果lpProcessAttributes参数为空（NULL），那么句柄不能被继承。<同上>  
			false,//    指示新进程是否从调用进程处继承了句柄。   
			0,  //  指定附加的、用来控制优先类和进程的创建的标  
				//  CREATE_NEW_CONSOLE  新控制台打开子进程  
				//  CREATE_SUSPENDED    子进程创建后挂起，直到调用ResumeThread函数  
			NULL, //    指向一个新进程的环境块。如果此参数为空，新进程使用调用进程的环境  
			NULL, //    指定子进程的工作路径  
			&si, // 决定新进程的主窗体如何显示的STARTUPINFO结构体  
			&pi  // 接收新进程的识别信息的PROCESS_INFORMATION结构体  
		))
		{
			cout << "create process success" << endl;

			//下面两行关闭句柄，解除本进程和新进程的关系，不然有可能不小心调用TerminateProcess函数关掉子进程  
	//      CloseHandle(pi.hProcess);  
	//      CloseHandle(pi.hThread);  
		}
		DWORD dwWaitResult = WaitForInputIdle(pi.hProcess, INFINITE);
		if (dwWaitResult == WAIT_TIMEOUT)
		{

		}
		if (WAIT_TIMEOUT == WAIT_FAILED)
		{
			int err = GetLastError();
		}
		if (WAIT_TIMEOUT == 0)
		{
			//成功
			return TRUE;
		}
		return FALSE;
	}

	std::vector<std::string> GetAllProcess()
	{
		std::vector<std::string> vct;
		PROCESSENTRY32 pe32;
		// 在使用这个结构之前，先设置它的大小
		pe32.dwSize = sizeof(pe32);

		// 给系统内的所有进程拍一个快照
		HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hProcessSnap == INVALID_HANDLE_VALUE)
		{
			printf(" CreateToolhelp32Snapshot调用失败！ \n");
			return vct;
		}

		BOOL bMore = ::Process32First(hProcessSnap, &pe32);
		std::wstring wsrProExeName;

		while (bMore)
		{
			wsrProExeName = pe32.szExeFile;
			/*printf(" 进程名称：%s \n", pe32.szExeFile);
			printf(" 进程ID号：%u \n\n", pe32.th32ProcessID);*/
			vct.push_back(wstring2string(wsrProExeName));
			bMore = ::Process32Next(hProcessSnap, &pe32);
		}
		// 不要忘记清除掉snapshot对象
		::CloseHandle(hProcessSnap);
		return vct;
	}
}